home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / kernel / stshadow.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  4KB  |  156 lines

  1. #if (CHIP == M68000)
  2. /* This file performs shadowing, a solution for the fork() problem
  3.  * on machines that have no relocation hardware.
  4.  */
  5.  
  6. #include "kernel.h"
  7. #include <minix/callnr.h>
  8. #include <minix/com.h>
  9. #include "proc.h"
  10.  
  11. #define    TRACE(x)    /* x */
  12.  
  13. PRIVATE int    flipwait;
  14.  
  15. #define    FLIPWAIT    5    /* units of 100ms between flips */
  16.  
  17. /*===========================================================================*
  18.  *                mkshadow                     * 
  19.  *===========================================================================*/
  20.  
  21. PUBLIC void mkshadow(p, c2)
  22. register struct proc *p;
  23. phys_clicks c2;
  24. {
  25.   phys_clicks c1, nc;
  26.  
  27.   TRACE(printf("mkshadow(%d): ",p->p_pid));
  28.   c1 = p->p_map[D].mem_phys;
  29.   if (p->p_shadow)
  30.     c1 = p->p_shadow;    /* father can be shadowed! */
  31.   p->p_shadow = c2;
  32.   nc = p->p_map[S].mem_phys - p->p_map[D].mem_phys + p->p_map[S].mem_len;
  33.   copyclicks(c1, c2, nc);
  34.   flipwait = FLIPWAIT;
  35. }
  36.  
  37. /*===========================================================================*
  38.  *                rmshadow                     * 
  39.  *===========================================================================*/
  40.  
  41. PUBLIC void rmshadow(p, basep, sizep)
  42. register struct proc *p;
  43. phys_clicks *basep, *sizep;
  44. {
  45. /* Three possibilities:
  46.  *   1. p is a shadow
  47.  *   2. p is real, but has one or more shadows
  48.  *   3. p is real without shadows
  49.  */
  50.   register struct proc *q;
  51.   register phys_clicks nc;
  52.  
  53.   TRACE(printf("rmshadow(%d)->",p->p_pid));
  54.   nc = p->p_map[S].mem_phys - p->p_map[D].mem_phys + p->p_map[S].mem_len;
  55.   if (p->p_shadow) {
  56.     *basep = p->p_shadow;
  57.     *sizep = nc;
  58.     p->p_shadow = 0;
  59.     TRACE(printf("(%x,%x)\n",*basep,*sizep));
  60.     return;
  61.   }
  62.   /*
  63.    * search for shadows
  64.    */
  65.   for (q = &proc[NR_TASKS+LOW_USER]; q < &proc[NR_TASKS+NR_PROCS]; q++) {
  66.     if (q->p_flags & P_SLOT_FREE)
  67.         continue;
  68.     if (q == p)
  69.         continue;
  70.     if (q->p_map[D].mem_phys != p->p_map[D].mem_phys)
  71.         continue;
  72.     if (q->p_shadow == 0)
  73.         panic("no shadow?", NO_NUM);
  74.     if (q->p_physio)
  75.         panic("rmshadow: cannot handle physio shadows", NO_NUM);
  76.     *basep = q->p_shadow;
  77.     *sizep = nc;
  78.     TRACE(printf("(%x,%x): ",*basep,*sizep));
  79.     copyclicks(q->p_shadow, p->p_map[D].mem_phys, nc);
  80.     if (q->p_flags == 0)
  81.         lock_unready(q);
  82.     q->p_shadow = 0;
  83.     if (q->p_flags == 0)
  84.         lock_ready(q);
  85.     return;
  86.   }
  87.   /*
  88.    * normal unshadowed process image
  89.    */
  90.   *basep = p->p_map[T].mem_phys;
  91.   *sizep = nc + p->p_map[T].mem_len;
  92.   TRACE(printf("(%x,%x)\n",*basep,*sizep));
  93. }
  94.  
  95. /*===========================================================================*
  96.  *                unshadow                     * 
  97.  *===========================================================================*/
  98.  
  99. PUBLIC void unshadow(p)
  100. register struct proc *p;
  101. {
  102.   register struct proc *q;
  103.  
  104.   TRACE(printf("unshadow(%d): ",p->p_pid));
  105.   if (flipwait) {
  106.     flipwait--;
  107.     return;
  108.   }
  109.   if (p->p_physio) {
  110.     TRACE(printf("physio(%d)\n",p->p_pid));
  111.     return;
  112.   }
  113.   /*
  114.    * find owner of real memory slot: same mem_phys, no shadow
  115.    */
  116.   for (q = &proc[NR_TASKS+LOW_USER]; ; q++) {
  117.     if (q == &proc[NR_TASKS+NR_PROCS])
  118.         panic("only shadow(s)", NO_NUM);
  119.     if (q->p_flags & P_SLOT_FREE)
  120.         continue;
  121.     if (q == p)
  122.         continue;
  123.     if (q->p_map[D].mem_phys != p->p_map[D].mem_phys)
  124.         continue;
  125.     if (q->p_shadow == 0)
  126.         break;
  127.   }
  128.   if (q->p_physio) {
  129.     TRACE(printf("physio(%d)\n",q->p_pid));
  130.     return;
  131.   }
  132.   /*
  133.    * exchange process images
  134.    */
  135.   flipclicks(
  136.     p->p_shadow,
  137.     q->p_map[D].mem_phys,
  138.     q->p_map[S].mem_phys - q->p_map[D].mem_phys + q->p_map[S].mem_len
  139.   );
  140.   flipwait = FLIPWAIT;
  141.   /*
  142.    * give ownership of shadow to q, changing queues if appropriate
  143.    */
  144.   lock_unready(p);
  145.   if (q->p_flags == 0)
  146.     lock_unready(q);
  147.   q->p_shadow = p->p_shadow;
  148.   p->p_shadow = 0;
  149.   lock_ready(p);
  150.   if (q->p_flags == 0)
  151.     lock_ready(q);
  152.   p->p_nflips++;
  153.   q->p_nflips++;
  154. }
  155. #endif
  156.